<?php

use JsonLowCode\Schema;
use JsonLowCode\Support\HigherOrderTapProxy;
use JsonLowCode\Support\Js;
use JsonLowCode\Support\JsParse;


if (! function_exists('tap')) {
    /**
     * Call the given Closure with the given value then return the value.
     *
     * @param  mixed  $value
     * @param  callable|Closure|null  $callback
     * @return mixed
     */
    function tap(mixed $value, callable|Closure $callback = null): mixed
    {
        if (is_null($callback)) {
            return new HigherOrderTapProxy($value);
        }

        $callback($value);

        return $value;
    }
}

if (!function_exists('strToUcWords')){
    /**
     * 将英文字符串 [hello world, hello-world, hello_world, hello,world] 转成 HelloWorld
     * @param string $word
     * @param string $replace
     * @return string
     */
    function strToUcWords(string $word, string $replace = ""): string
    {
        $word = str_replace(["-","_",","]," ",$word);
        if ($replace){
            $word = str_replace($replace," ",$word);
        }
        return str_replace(" ","",ucwords($word));
    }
}

if (!function_exists('isSfcView')){
    /**
     * 是否sfc单文件视图
     * @param string $view
     * @return bool
     */
    function isSfcView(string $view = ""): bool
    {
        $pattern1 = "/<script(.*?)>(.*?)export(.*?)default(.*?){(.*?)}(.*?)<\/script>/s";
        $pattern2 = "/<script(.*?)setup(.*?)>(.*?)<\/script>/s";
        $pattern3 = "/<template(.*?)>(.*?)<\/template>/s";
        $pattern4 = "/<style(.*?)>(.*?)<\/style>/s";
        $check1 = preg_match($pattern1, $view);
        $check2 = preg_match($pattern2, $view);
        $check3 = preg_match($pattern3, $view);
        $check4 = preg_match($pattern4, $view);
        if (($check1&&$check3)||($check2&&$check3)||($check3&&$check4)){
            return true;
        }
        if ($check3&&!$check1&&!$check2&&!$check4){
            return true;
        }
        return false;
    }
}


if (!function_exists('getObjectCode')){
    /**
     * 获取类方法的代码
     * @param string $class
     * @param string $method
     * @return string
     * @throws ReflectionException
     */
    function getObjectCode(string $class, string $method = ""): string
    {
        $reflectionClass = new ReflectionClass($class);
        $source = file($reflectionClass->getFileName());
        if (!$method){
            return trim(implode(" ",$source),"\r\n");
        }
        $reflectionMethod = $reflectionClass->getMethod($method);
        $startLine = $reflectionMethod->getStartLine() - 1;
        $endLine = $reflectionMethod->getEndLine() - 1;
        $codes = array_slice(
            file($reflectionMethod->getFileName()),
            $startLine,
            $endLine - $startLine + 1
        );
        $codes = array_map(fn($code)=>preg_replace('/^    /', '', $code), $codes);
        return trim(implode('',$codes),"\r\n");
    }
}


if (!function_exists('scriptFunc')){
    /**
     * 函数脚本
     * @param string $script
     * @param string|array $params
     * @return string
     */
    function scriptFunc(string $script, string|array $params = ""): string
    {
        $params = is_array($params)?implode(",",$params):$params;
        if ($params){
            return "function({$params}){\n{$script}\n}";
        }else{
            return "function(){\n{$script}\n}";
        }
    }
}

if (!function_exists('jsToggleEvent')){
    /**
     * js bool 变量变换事件
     * @param string $key
     * @return string
     */
    function jsToggleEvent(string $key): string
    {
        return scriptFunc(Js::state($key)."=!".Js::state($key).";");
    }
}

if (!function_exists('JSExpression')){
    /**
     * JSExpression 数组对象函数
     * @param mixed $value
     * @param mixed $extends
     * @return JsParse
     */
    function JSExpression(mixed $value, mixed $extends = []): JsParse
    {
        return JsParse::jsExpression($value,$extends);
    }
}

if (!function_exists('JSFunction')){
    /**
     * JSFunction 数组对象函数
     * @param mixed $value
     * @param array $params
     * @return JsParse
     */
    function JSFunction(mixed $value, array $params = []): JsParse
    {
        return JsParse::jsFunction($value,$params);
    }
}

if (!function_exists('JSSlot')){
    /**
     * @param Schema|null $value
     * @param array $params
     * @return JsParse
     */
    function JSSlot(Schema $value = null, array $params = []): JsParse
    {
        return JsParse::jsSlot($value,$params);
    }
}

if (!function_exists('stateToNestedArray')){
    /**
     * @param array $states
     * @param string $string
     * @param mixed|null $value
     * @return void
     */
    function stateToNestedArray(array &$states, string $string, mixed $value = null): void
    {
        $parts = explode('.', $string);
        $key = array_pop($parts); // 获取最后一个键
        $currentState = &$states; // 引用原始数组，用于修改
        // 遍历除了最后一个键以外的部分来找到正确的嵌套级别
        foreach ($parts as $part) {
            if (!isset($currentState[$part])) {
                $currentState[$part] = []; // 如果键不存在，则创建它
            }
            $currentState = &$currentState[$part]; // 移动到下一个嵌套级别
        }
        // 设置或更新最后一个键的值
        if (isset($currentState[$key])){
            $currentState[$key] = $value?:$states[$key]; // 默认设置为空字符串
        }else{
            $currentState[$key] = $value; // 默认设置为空字符串
        }
    }
}




